<template>
  <div class="product-card-spec">
    <MerakXTable
      ref="tableRef"
      v-bind="tableState"
      :columns="tableColumns"
      :column-type="tableColumnType"
      @tool-click="handleToolClick"
    >
      <template #tools>
        <el-input
          v-model="searchValue"
          style="width: 200px"
          clearable
          :placeholder="$t('goods_archive.sku_product')"
          :suffix-icon="Search"
          @change="handleSearch"
        />
        <el-select v-model="searchSelect" style="width: 200px" @change="handleSearch">
          <el-option :value="0" label="全部" />
          <el-option :value="1" label="套号" />
          <el-option :value="2" label="单码" />
        </el-select>
      </template>
      <template #custom-tip-column="{ column }">
        <div class="merak-control-tip">
          <span>{{ column.title }}</span>
          <el-tooltip v-if="!!column.params?.tip" popper-class="merak-control-tip-popper" placement="top">
            <el-icon>
              <info-filled />
            </el-icon>
            <template #content>
              <div v-html="column.params.tip" />
            </template>
          </el-tooltip>
        </div>
      </template>
      <template #custom-part="{ row }">
        <el-button
          class="product-card-table-button"
          type="primary"
          link
          @click="Object.assign(partState, { visible: true, row })"
        >
          {{ $t("merak.detail") }}
        </el-button>
      </template>
      <template #custom-device="{ row }">
        <el-button
          class="product-card-table-button"
          type="primary"
          link
          @click="Object.assign(deviceState, { visible: true, row })"
        >
          {{ $t("merak.detail") }}
        </el-button>
      </template>
      <template #custom-images="{ row }">
        <div class="product-card-spec-images">
          <el-image
            v-if="!!row.images?.length"
            fit="cover"
            style="cursor: pointer"
            :src="`${row.images[0]?.file_url}_60x60.jpg`"
            @click="handleLookImage(row.images)"
          />
          <el-image v-else fit="cover" :src="DefaultImage" />
        </div>
      </template>
      <template #custom-handle="{ row }">
        <el-button type="primary" link @click="Object.assign(drawerState, { visible: true, type: 'edit', row })">
          {{ $t("merak.edit") }}
        </el-button>
        <el-button type="primary" link @click="Object.assign(drawerState, { visible: true, type: 'copy', row })">
          {{ $t("merak.copy") }}
        </el-button>
        <el-button type="danger" link @click="handleDelete(row)">
          {{ $t("merak.delete") }}
        </el-button>
      </template>
    </MerakXTable>
    <!-- 抽屉 -->
    <el-drawer
      v-model="drawerState.visible"
      modal-class="sku_detail_drawer"
      size="50%"
      direction="rtl"
      destroy-on-close
      :title="drawerTitle"
      :append-to-body="true"
    >
      <SpecForm
        :type="drawerState.type"
        :row="drawerState.row"
        :formConfig="props.config"
        :specsInitial="props.info"
        :formReadonly="props.readonly"
        :formValue="props.data"
        :tableData="searchData"
        @close="handleClose"
      />
    </el-drawer>
    <!-- 部件抽屉 -->
    <el-drawer
      v-model="partState.visible"
      modal-class="sku_detail_drawer"
      size="50%"
      direction="rtl"
      destroy-on-close
      :title="$t('goods_archive.part')"
      :append-to-body="true"
    >
      <PartForm :row="partState.row" @close="handleClosepartState" />
    </el-drawer>
    <!-- 设备抽屉 -->
    <el-drawer
      v-model="deviceState.visible"
      modal-class="sku_detail_drawer"
      size="50%"
      direction="rtl"
      destroy-on-close
      :title="$t('goods_archive.device')"
      :append-to-body="true"
      :row="drawerState.row"
    >
      <DeviceForm :row="deviceState.row" @close="handleCloseDeviceState" />
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import type { UserAuthType } from "@/api/modules/user";

import { type Ref, h, getCurrentInstance, inject, ref, reactive, computed, watch } from "vue";

import { useRoute, useRouter } from "vue-router";

import { useTabsStore } from "@/stores/modules/tabs";

import { ElInput, ElDrawer, ElTooltip, ElIcon, ElButton, ElImage, ElMessage, ElMessageBox } from "element-plus";

import { Search, InfoFilled } from "@element-plus/icons-vue";

import MerakXTable, { MerakXTableInstance, MerakXTableProps, MerakXTableColumn } from "@/components/MerakXTable";

import SpecForm, { FormType } from "./SpecForm.vue";
import PartForm from "./PartForm.vue";
import DeviceForm from "./DeviceForm.vue";

import { ResultEnum } from "@/enums/httpEnum";
import { InitParams, getInitData } from "@/api/modules/goodsArchive/addGoodsArchive";
import { batchDeleteApi } from "@/api/modules/goodsArchive/list/information";

import { confirmWarningMsg } from "@/utils/messageUtils";

import { api as viewerApi } from "v-viewer";

import DefaultImage from "@/assets/images/goods_img.webp";

const props = defineProps<{
  // 初始化请求队列 id
  queueId?: string;
  // 表单项动态列数
  span: number;
  // 权限
  auth: UserAuthType;
  // 编辑状态
  editor: boolean;
  // 表单配置
  config: Record<string, any>;
  // 渲染数据
  info: Record<string, any>;
  // 回显数据
  data: Array<Record<string, any>>;
  // 只读字段
  readonly: Array<string>;
  // 表头数据
  tableHeader: Record<string, any>;
}>();

const emits = defineEmits<{
  freight: [id: string | number];
}>();

const currentInstance = getCurrentInstance();

const { query, fullPath, name: routeName } = useRoute();

const router = useRouter();

const { removeTabs } = useTabsStore();

const topProductId = inject<Ref<string | number>>("topProductId");

const countdown = ref(5);

const searchValue = ref("");

const searchSelect = ref(0);

const searchData = reactive<Array<Record<string, any>>>([]);

const drawerState = reactive<{ visible: boolean; type: FormType; row?: Record<string, any> }>({
  visible: false,
  type: "default"
});

const partState = reactive<{ visible: boolean; row?: Record<string, any> }>({
  visible: false
});

const deviceState = reactive<{ visible: boolean; row?: Record<string, any> }>({
  visible: false
});

const tableRef = ref<MerakXTableInstance>();

const tableState = reactive<MerakXTableProps>({
  columnsByStore: [],
  loading: false,
  maxHeight: 9999,
  rowHeight: 46,
  rowKey: "product_id",
  toolbar: ["refresh"],
  pagination: false,
  params: {},
  data: []
});

const tableColumns = computed(() => {
  const columns: MerakXTableColumn[] = [
    {
      field: "images",
      fixed: "left",
      width: 55,
      resizable: false,
      slots: { default: "custom-images" }
    },
    ...Object.keys(props.tableHeader).map(key => {
      const col: MerakXTableColumn = {
        field: `${key}_txt`,
        title: props.tableHeader?.[key]
      };
      switch (key) {
        case "sku":
          Object.assign(col, {
            width: 220,
            fixed: "left",
            slots: { header: "custom-tip-column" },
            params: {
              tip: currentInstance?.proxy?.$t("goods_archive.spu_sku_tip")
            }
          });
          break;
        case "size":
          Object.assign(col, {
            slots: { header: "custom-tip-column" },
            params: {
              tip: currentInstance?.proxy?.$t("goods_archive.size_tip")
            }
          });
          break;
        case "qifa_color_id":
          Object.assign(col, {
            minWidth: 100,
            slots: { header: "custom-tip-column" },
            params: {
              tip: currentInstance?.proxy?.$t("goods_archive.qf_color_tip")
            }
          });
          break;
        case "supplier_color_id":
          Object.assign(col, {
            minWidth: 100,
            slots: { header: "custom-tip-column" },
            params: {
              tip: currentInstance?.proxy?.$t("goods_archive.supplier_color_tip")
            }
          });
          break;
        default:
          break;
      }
      return col;
    })
  ];
  if (query.t_id === "14") {
    columns.unshift({
      field: "part",
      title: currentInstance?.proxy?.$t("goods_archive.part"),
      slots: { default: "custom-part" }
    });
  }
  if (query.t_id === "24") {
    columns.unshift({
      field: "device",
      title: currentInstance?.proxy?.$t("goods_archive.device"),
      slots: { default: "custom-device" }
    });
  }
  return columns;
});

const tableColumnType = computed(() => {
  const columnType: MerakXTableProps["columnType"] = [];
  if (!!props.auth.edit?.show) {
    columnType.push({ type: "handle", width: 180, slot: "custom-handle" });
  }
  return columnType;
});

const drawerTitle = computed(() => {
  const titleMap: Record<FormType, string> = {
    default: currentInstance?.proxy?.$t("goods_archive.add_new_art_no") ?? "",
    edit: drawerState.row?.sku,
    copy: currentInstance?.proxy?.$t("goods_archive.copy_art_no") ?? ""
  };
  return titleMap[drawerState.type];
});

const queryData = async (product_id?: string | number) => {
  const params: InitParams = {
    type_id: query.t_id?.toString(),
    goods_id: query.g_id?.toString(),
    product_id: product_id ?? topProductId?.value ?? query.p_id?.toString(),
    is_suite: query.s_id == "1" ? 1 : 0,
    is_copy: 0
  };
  tableState.loading = true;
  await getInitData(params).then(async ({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      searchData.length = 0;
      searchData.push(...[...(data.form_value?.spec ?? [])]);
      await handleSearch();
    } else if (code === 3000) {
      const { product_id } = data;
      if (!!product_id) {
        router.replace({ name: routeName ?? "", query: { ...query, p_id: product_id } });
        // queryData(product_id);
        // emits("freight", product_id);
      }
    } else {
      const timer = setInterval(() => {
        if (countdown.value <= 1) {
          ElMessageBox.close();
          clearInterval(timer);
          removeTabs(fullPath);
          return;
        }
        countdown.value--;
      }, 1000);
      ElMessageBox({
        type: "warning",
        title: currentInstance?.proxy?.$t("merak.tip_modal"),
        message: () =>
          h(
            "p",
            null,
            `${currentInstance?.proxy?.$t("goods_archive.delete_product_tip_one")} ${
              countdown.value
            } ${currentInstance?.proxy?.$t("goods_archive.delete_product_tip_two")}`
          ),
        showClose: false,
        showCancelButton: false,
        closeOnClickModal: false,
        closeOnPressEscape: false,
        confirmButtonText: currentInstance?.proxy?.$t("goods_archive.close_page")
      }).then(() => {
        clearInterval(timer);
        removeTabs(fullPath);
        router.back();
      });
    }
  });
  tableState.loading = false;
};

const handleSearch = async () => {
  const tableData = [...searchData].filter(row => row.sku.includes(searchValue.value));
  switch (searchSelect.value) {
    case 1:
      tableState.data = tableData.filter(row => row.num_in_packing > 1);
      break;
    case 2:
      tableState.data = tableData.filter(row => row.num_in_packing === 1);
      break;
    default:
      tableState.data = tableData;
      break;
  }
  return Promise.resolve();
};

const handleToolClick: MerakXTableInstance["onTool-click"] = type => {
  if (type === "refresh") {
    queryData();
  }
};

const handleLookImage = (images?: Array<Record<string, any>>) => {
  viewerApi({
    images: [...(images ?? [])],
    options: {
      toolbar: true,
      url: "file_url",
      fullscreen: false,
      initialViewIndex: 0
    }
  });
};

const handleDelete = (row: Record<string, any>) => {
  const { type_id, product_id } = row;
  if (!type_id || !product_id) return;
  confirmWarningMsg({
    msg: currentInstance?.proxy?.$t("goods_archive.delete_product_message") ?? "",
    callback: (status: string) => {
      if (status === "confirm") {
        batchDeleteApi({
          type_id: query.t_id?.toString(),
          product_ids: [product_id]
        }).then(({ code, errors }) => {
          if (code == ResultEnum.SUCCESS) {
            queryData();
            ElMessage.success(currentInstance?.proxy?.$t("goods_archive.delete_product_success"));
          } else if (Array.isArray(errors)) {
            const error = errors?.[0];
            if (error?.message) {
              ElMessage.error(error.message);
            }
          }
        });
      }
    }
  });
};

const handleClose = (saved: boolean = false) => {
  if (saved) {
    // 刷新列表
    queryData();
  }
  drawerState.visible = false;
};

const handleClosepartState = (saved: boolean = false) => {
  if (saved) {
    // 刷新列表
    queryData();
  }
  partState.visible = false;
};

const handleCloseDeviceState = (saved: boolean = false) => {
  if (saved) {
    // 刷新列表
    queryData();
  }
  deviceState.visible = false;
};

watch(
  () => props.data,
  () => {
    tableState.data = [...props.data];
    searchData.push(...props.data);
    const current = tableState.data.find(row => row.product_id?.toString() === query.p_id?.toString());
    if (!!current) {
      const timer = requestAnimationFrame(() => {
        tableRef.value?.gridRef?.setCurrentRow(current);
        cancelAnimationFrame(timer);
      });
    }
  },
  { once: true, immediate: true }
);

defineExpose({
  handleAdd: () => Object.assign(drawerState, { visible: true, type: "default" })
});
</script>

<style scoped lang="scss">
.product-card-spec-images {
  margin-left: calc(14px - var(--merak-table-cell-padding));
  line-height: 1;
  .el-image {
    width: 40px;
    height: 40px;
    :deep(.el-image__error) {
      font-size: 8px;
    }
    img {
      width: 100%;
      height: 100%;
    }
  }
}
.product-card-table-button {
  margin: 0;
  padding: 0;
  min-width: auto;
  border: none;
}
</style>
